package com.ayg.insurance.service.batch.userorder;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;

import com.ayg.insurance.dao.DealProviderOrderDao;
import com.ayg.insurance.dao.ProviderOrderDao;
import com.ayg.insurance.dao.UserOrderDao;
import com.ayg.insurance.dao.impl.HibernateDao.BatchIterator;
import com.ayg.insurance.dao.impl.HibernateDao.BatchIteratorWithTotalCount;
import com.ayg.insurance.model.enums.UnionOrderStatus;
import com.ayg.insurance.model.order.DealProviderOrder;
import com.ayg.insurance.model.order.ProviderOrder;
import com.ayg.insurance.model.order.UserOrder;
import com.ayg.insurance.model.order.UserOrder.HandleState;
import com.ayg.insurance.model.order.UserOrder.UserOrderStatus;
import com.ayg.insurance.model.user.UserInfo.UserStatus;
import com.ayg.insurance.service.state.order.ProviderOrderState;
import com.ayg.insurance.service.state.user.UserState;
import com.ayg.insurance.service.subservice.BatchOperationWithProgressBarSubService;
import com.ayg.insurance.service.subservice.StrategyFactory;
import com.ayg.insurance.service.subservice.BatchOperationWithProgressBarSubService.Invoker;
import com.ayg.insurance.service.subservice.BatchOperationWithProgressBarSubService.Processor;
import com.ayg.insurance.vo.BatchOptParam;

public class UserOrderBatchOperation {
	
	@Resource UserOrderDao userOrderDao;
	@SuppressWarnings("rawtypes")
	@Resource BatchOperationWithProgressBarSubService processSubService;
	
	public final void batchOperater(String key, final BatchOptParam param, final UserOrderBatchInvoker invokder) {
		processSubService.doOnBatchIterator(key, new Invoker() {
			@Override
			public void handle(Processor processor) {
				inner(param, invokder, processor);
			}
		});
	}

	@SuppressWarnings("rawtypes")
	private void inner(BatchOptParam param, UserOrderBatchInvoker invokder, Processor processor) {
		// 1 查询数据
		final BatchIteratorWithTotalCount userOrders = userOrder(param);
		final int totalCount = userOrders.getTotalCount() * 2;
		processor.setTotal(totalCount);
		processor.increase(1);
		
		final Set<Long> providerOrderIds = new HashSet<Long>();
		final Set<Long> dealProviderOrderIds = new HashSet<Long>();
		
		final BatchIterator batchIterator = userOrders.getBatchIterator();
		while (batchIterator.hasNext()) {
			final UserOrder userOrder = (UserOrder) batchIterator.next();
			processor.increase(1);
			
			providerOrderIds.add(userOrder.getProviderOrderId());
			dealProviderOrderIds.add(userOrder.getDealProviderOrderId());
			
			// 1 更新状态
			final HandleState otherStatus = otherHandleStatus(userOrder, param);
			userOrder.setStatus(invokder.userOrderStatus(otherStatus).value);
			
			// 2 更新办理单单数
			updateDealProviderOrderCounts(userOrder);
			
			// 3 更新接单单数
			updateProviderOrderCounts(userOrder);
			
			// 4 特殊操作，如生成补收单、生成退费单、累加补收金额、累加退费金额
			invokder.handleWithEachUserOrder(userOrder);
			
			userOrderDao.update(userOrder);
		}
		
		// 5 尝试更新办理订单状态
		updateProviderOrdersStatus(providerOrderIds);
		
		// 6 尝试更新接单订单状态
		updateDealProviderOrdersStatus(dealProviderOrderIds);
		
		// 最后的额外处理
		invokder.handleAfterUserOrders();
	}
	
	/**
	 * 1.遍历办理单
	 * 3.根据订单ID查找redis总人数所在状态总数对比情况
	 * 2.根据当前订单状态判断是否可以更改为下一个状态
	 * @param dealProviderOrderIds
	 * @author owen.he
	 */
	private void updateDealProviderOrdersStatus(Set<Long> dealProviderOrderIds) {
		
	}

	/**
	 * 同上
	 * @param providerOrderIds
	 * @author owen.he
	 */
	private void updateProviderOrdersStatus(Set<Long> providerOrderIds) {
		
	}

	private void updateProviderOrderCounts(UserOrder userOrder) {
		// TODO 更新接单供应商单单数 Merry
	}

	private void updateDealProviderOrderCounts(UserOrder userOrder) {
		// TODO 更新办理供应单单数 Merry
	}

	private HandleState otherHandleStatus(UserOrder userOrder, BatchOptParam param) {
		// TODO 返回另外一个项目的状态 Michael
		return null;
	}

	@SuppressWarnings("rawtypes")
	private BatchIteratorWithTotalCount userOrder(BatchOptParam param) {
		// TODO 查询用户单 大杰哥
		return null;
	}

	public static interface UserOrderBatchInvoker {

		/**
		 * 实现两个状态组合，得到用户单状态
		 * @param other
		 * @return
		 */
		abstract UserOrderStatus userOrderStatus(HandleState other);
		
		abstract void handleWithEachUserOrder(UserOrder userOrder);
		
		/**
		 * 由子类实现的针对每个单个特殊操作
		 * @param userOrder
		 * @param insuranceOrCpf
		 */
		abstract void doWithEachUserOrder(UserOrder userOrder, int insuranceOrCpf);
		
		abstract void handleAfterUserOrders();
	}
	
	public static class BatchUserOrder {
		int count;
		Iterator<UserOrder> userOrders;
	}
}
